#!/usr/bin/env python
#  Copyright (c) 2010
#  The Regents of the University of Michigan
#  All Rights Reserved

#  Permission is granted to use, copy, create derivative works, and
#  redistribute this software and such derivative works for any purpose,
#  so long as the name of the University of Michigan is not used in
#  any advertising or publicity pertaining to the use or distribution
#  of this software without specific, written prior authorization. If
#  the above copyright notice or any other identification of the
#  University of Michigan is included in any copy of any portion of
#  this software, then the disclaimer below must also be included.

#  This software is provided as is, without representation or warranty
#  of any kind either express or implied, including without limitation
#  the implied warranties of merchantability, fitness for a particular
#  purpose, or noninfringement.  The Regents of the University of
#  Michigan shall not be liable for any damages, including special,
#  indirect, incidental, or consequential damages, with respect to any
#  claim arising out of or in connection with the use of the software,
#  even if it has been or is hereafter advised of the possibility of
#  such damages.
from pydht import dht, dhtutil

import event
import logging
import random
import signal
import sys

class DHTClient(dht.DHTClient):
  def _handle_recv(self):
    print 'got something!'
    return dht.DHTClient._handle_recv(self)

  def handle_reply(self, reply, sender, *args):
    print 'Reply received from %s' % str(sender)
    print reply

  handle_ping_reply = handle_reply

  handle_find_node_reply = handle_reply

  handle_stats_reply = handle_reply

  handle_find_value_reply = handle_find_node_reply

  handle_store_reply = handle_reply


def main(argv):
  ext_ip = argv[1]
  contact_ip, start_port, port_count = argv[2:5]
  rpc = argv[5]
  start_port = int(start_port)
  port_count = int(port_count)

  client = DHTClient((ext_ip, 6969))
  print 'my ID: %s' % dht.compute_hex_node_id(ext_ip, 6969)
  for contact_port in xrange(start_port, start_port + port_count):
    timeout_interval = 1 * (contact_port - start_port) # 1 second between each.
    contact = dht.make_contact((contact_ip, contact_port))
    if rpc == 'find_node':
      event.timeout(timeout_interval,
                    lambda: client.send_find_node(contact,
                                                  client.dht_id))
    elif rpc in ('ping', 'stats'):
      method = client.send_ping_request if rpc == 'ping' else client.send_stats_request
      event.timeout(timeout_interval,
                    lambda: method(contact))
    elif rpc == 'store':
      spoof_id = eval(argv[6])
      version = int(argv[7])
      key = hex(dhtutil.intify(dht.compute_node_id(contact)) + random.randint(-1000, 1000))[2:].rstrip('L').decode('hex')
      print 'node id: %r' % dht.compute_node_id(contact)
      print 'key: %r' % key
      value = 'swolchok wuz here %d' % version
      event.timeout(timeout_interval,
                    lambda: client.send_store_request(contact, key, value,
                                                      version, spoof_id))
    elif rpc == 'find_value':
      key = eval(argv[6])
      event.timeout(timeout_interval,
                    lambda: client.send_find_value(contact, key))
    else:
      print >> sys.stderr, 'bad RPC!'
      return
      
  event.signal(signal.SIGTERM, event.abort)
  event.signal(signal.SIGINT, event.abort)
  event.timeout(30, event.abort)
  event.dispatch()

if __name__ == '__main__':
  logging.basicConfig(filename="vp.log", level=logging.DEBUG)
  main(sys.argv)
